package cn.geminis.data.jpa.filter;

import cn.geminis.data.jpa.QueryPredicateBuilder;
import cn.geminis.data.jpa.entity.Student;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.jpa.domain.Specification;

import java.time.LocalDateTime;

@Getter
@Setter
@Builder
public class StudentFilter implements Specification<Student> {

    private String[] include;
    private String id;
    private String name;
    private String nameLike;
    private Boolean nameIsNull;
    private Boolean nameIsNotNull;
    private Integer ageGreaterThan;
    private Integer ageLessThan;
    private Integer ageGreaterThanOrEqual;
    private Integer ageLessThanOrEqual;
    private Integer[] ageIn;
    private LocalDateTime birthdayGreaterThan;
    private LocalDateTime birthdayLessThan;
    private String bookName;
    private String className;
    private Boolean bookIsNotEmpty;
    private Boolean bookIsEmpty;

    @Override
    public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {

        var builder = new QueryPredicateBuilder<>(root, query, criteriaBuilder);
        builder.include(include);
        builder.equal("id", id);
        builder.equal("name", name);
        builder.isNull("name", nameIsNull);
        builder.isNotNull("name", nameIsNotNull);
        builder.like("name", nameLike);
        builder.greaterThan("age", ageGreaterThan);
        builder.lessThan("age", ageLessThan);
        builder.greaterThanOrEqualTo("age", ageGreaterThanOrEqual);
        builder.lessThanOrEqualTo("age", ageLessThanOrEqual);
        builder.in("age", ageIn);
        builder.equal("books.name", bookName);
        builder.equal("classes.name", className);
        builder.isNotEmpty("books", bookIsNotEmpty);
        builder.isEmpty("books", bookIsEmpty);

        return builder.build();
    }
}
